package com.tangtang.gulimall.product.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tangtang.common.utils.PageUtils;
import com.tangtang.common.utils.Query;

import com.tangtang.gulimall.product.dao.CategoryDao;
import com.tangtang.gulimall.product.entity.CategoryEntity;
import com.tangtang.gulimall.product.service.CategoryService;

import javax.annotation.Resource;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    //之前的ssm写法需要引入mapper或者dao层里面的内容,但是mybatisplus里面不需要引入，直接使用baseMapper即可直接调用CategoryDao
    //里面的方法。
    @Resource
    CategoryDao categoryDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CategoryEntity> listWitchTree() {
        //1.查询出所有分类
        /*QueryWrapper<CategoryEntity> queryWrapper = new QueryWrapper<CategoryEntity>();
        queryWrapper.eq("","");//查询等于什么条件*/
        List<CategoryEntity> categoryEntityList =  baseMapper.selectList(null);//如果没有查询条件，可以直接给空(代表查询全部)

        //2.组装成父子的树形结构
        //2.1需要查询categoryEntityList里面的一级菜单(Stream写法用于数据量小，如果操作次数多的话用下面的便利方法快)
        List<CategoryEntity> listmeun = categoryEntityList.stream().filter(CategoryEntity->{
            return CategoryEntity.getParentCid() == 0;//查出父类为0的菜单id
        }).map((meun)->{
            meun.setChildren(getChildrens(meun,categoryEntityList));//父类id（可以说是一级id），所有的菜单id
            return meun;
        }).sorted((meun1,meun2)->{
            return (meun1.getSort()==null?0:meun1.getSort()) - (meun2.getSort()==null?0:meun2.getSort());//进行排序，用一个三元付判断是否为空
        }).collect(Collectors.toList());

        //接2.1的平常加入写法
        List<CategoryEntity> listmeun1 = new ArrayList<>();
        for (CategoryEntity categoryEntity:categoryEntityList) {
            if (categoryEntity.getParentCid() == 0) {
                categoryEntity.setChildren(getChildrens1(categoryEntity, categoryEntityList));
                listmeun1.add(categoryEntity);//将等于0层的数据全部加入新的list中
                //正常的递归调用中，排序方法得自己来写
                //这里的排序可以使用Collections.sort();正序，或者Collections.reverse();逆序来进行排序写法
            }
        }
        //return categoryEntityList;//直接返回所有数据
        return listmeun;//返回一级菜单，返回listmeun或者listmeun1(这边需要写一些逻辑查询，所以listmeun1暂时下不返回值)
    }

    //第一个参数是获取对应父类的子类id，然后根据父类id查新第二个参数里面的子类
    //递归查找子菜单
    private List<CategoryEntity> getChildrens(CategoryEntity root,List<CategoryEntity> all){
        //就类似上面的过滤写法一样
        List<CategoryEntity> chrildmeunlist = all.stream().filter(categoryEntity ->{
            //这个判断的意思是，当前的子类菜单的id等于指定的父类id，就是指定的父类id的子菜单
            return categoryEntity.getParentCid() == root.getCatId();
        }).map(categoryEntity->{
            //找子菜单的递归查询
            categoryEntity.setChildren(getChildrens(categoryEntity,all));
            return categoryEntity;
        }).sorted((meun1,meun2)->{
            return (meun1.getSort()==null?0:meun1.getSort()) - (meun2.getSort()==null?0:meun2.getSort());//查找完子菜单后再进行排序
        }).collect(Collectors.toList());

        return chrildmeunlist;
    }

    //正常写法的递归
    private List<CategoryEntity> getChildrens1(CategoryEntity root,List<CategoryEntity> all){
        List<CategoryEntity> childrenlist = new ArrayList<>();//如果将后面的子类都放在这个集合里面
        for (CategoryEntity categoryEntity:all) {
            if (categoryEntity.getParentCid()==root.getCatId()){
                categoryEntity.setChildren(getChildrens1(categoryEntity,all));
                childrenlist.add(categoryEntity);//将子类数据放入集合中
                //正常的递归调用中，排序方法得自己来写
            }
        }
        return childrenlist;
    }

    //这个todo代表的意识是，这个不确定还需要做什么，先留着
    @Override
    public void removeMenuByIds(List<Long> catids) {
        //TODO 检查菜单是否被别的地方引用，如果被引用，则此时不能被删除，没有被引用的情况下，
        // 则可以进行删除（当然也可以根据id进行直接强行删除）

        //目前做的是逻辑删除，需要配置一下文件
        categoryDao.deleteBatchIds(catids);
    }

    @Override
    public Long[] findCatelogpath(Long catelogpath) {
        List<Long> paths = new ArrayList<Long>();
        //第一步得先查出当前分类的信息(这里面有一个顶级service，可以调用this方法) this.getById(catelogpath);
        //如果categoryEntityid的父类id不为0，则接着继续查询(调用递归方法)
        List<Long>  parentpath =  getparentid(catelogpath,paths);
        System.out.println("未逆序的list集合为："+parentpath);
        //如果加上这个就变成升序，下面的reverse就变成了降序
        //Collections.sort(parentpath);
        //这单用的话是反转的意思，如果在配合上sort的升序，就是降序的意思
        //这里代表反转
        Collections.reverse(parentpath);//单用，可能也被称为逆序
        System.out.println("反转后的结果为："+parentpath);
        return parentpath.toArray(new Long[parentpath.size()]);
    }

    //循环查询父类的id
    private List<Long> getparentid(Long catelogid,List<Long> paths)
    {
        //将当前收集到的id添加到paths里面
        paths.add(catelogid);
        //收集当前id
        CategoryEntity categoryEntityid = categoryDao.selectById(catelogid);
        if(categoryEntityid.getParentCid()!=0)
        {
            //如果父类id不为0，则表示当前还有父类id，则就查询
            getparentid(categoryEntityid.getParentCid(),paths);
        }
        //查询完成以后，返回相应的值
        return paths;
    }
}